Skip to contentMethod: ByteArrayDataSource(byte[], String)
1: /*
2: * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package jakarta.mail.util;
18:
19: import java.io.*;
20:
21: import jakarta.activation.*;
22: import jakarta.mail.internet.*;
23:
24: /**
25: * A DataSource backed by a byte array. The byte array may be
26: * passed in directly, or may be initialized from an InputStream
27: * or a String.
28: *
29: * @since JavaMail 1.4
30: * @author John Mani
31: * @author Bill Shannon
32: * @author Max Spivak
33: */
34: public class ByteArrayDataSource implements DataSource {
35: private byte[] data;        // data
36: private int len = -1;
37: private String type;        // content-type
38: private String name = "";
39:
40: static class DSByteArrayOutputStream extends ByteArrayOutputStream {
41:         public byte[] getBuf() {
42:          return buf;
43:         }
44:
45:         public int getCount() {
46:          return count;
47:         }
48: }
49:
50: /**
51: * Create a ByteArrayDataSource with data from the
52: * specified InputStream and with the specified MIME type.
53: * The InputStream is read completely and the data is
54: * stored in a byte array.
55: *
56: * @param        is        the InputStream
57: * @param        type        the MIME type
58: * @exception        IOException        errors reading the stream
59: */
60: public ByteArrayDataSource(InputStream is, String type) throws IOException {
61:         DSByteArrayOutputStream os = new DSByteArrayOutputStream();
62:         byte[] buf = new byte[8192];
63:         int len;
64:         while ((len = is.read(buf)) > 0)
65:          os.write(buf, 0, len);
66:         this.data = os.getBuf();
67:         this.len = os.getCount();
68:
69:         /*
70:          * ByteArrayOutputStream doubles the size of the buffer every time
71:          * it needs to expand, which can waste a lot of memory in the worst
72:          * case with large buffers. Check how much is wasted here and if
73:          * it's too much, copy the data into a new buffer and allow the
74:          * old buffer to be garbage collected.
75:          */
76:         if (this.data.length - this.len > 256*1024) {
77:          this.data = os.toByteArray();
78:          this.len = this.data.length;        // should be the same
79:         }
80: this.type = type;
81: }
82:
83: /**
84: * Create a ByteArrayDataSource with data from the
85: * specified byte array and with the specified MIME type.
86: *
87: * @param        data        the data
88: * @param        type        the MIME type
89: */
90: public ByteArrayDataSource(byte[] data, String type) {
91: this.data = data;
92:         this.type = type;
93: }
94:
95: /**
96: * Create a ByteArrayDataSource with data from the
97: * specified String and with the specified MIME type.
98: * The MIME type should include a <code>charset</code>
99: * parameter specifying the charset to be used for the
100: * string. If the parameter is not included, the
101: * default charset is used.
102: *
103: * @param        data        the String
104: * @param        type        the MIME type
105: * @exception        IOException        errors reading the String
106: */
107: public ByteArrayDataSource(String data, String type) throws IOException {
108:         String charset = null;
109:         try {
110:          ContentType ct = new ContentType(type);
111:          charset = ct.getParameter("charset");
112:         } catch (ParseException pex) {
113:          // ignore parse error
114:         }
115:         charset = MimeUtility.javaCharset(charset);
116:         if (charset == null)
117:          charset = MimeUtility.getDefaultJavaCharset();
118:         // XXX - could convert to bytes on demand rather than copying here
119:         this.data = data.getBytes(charset);
120:         this.type = type;
121: }
122:
123: /**
124: * Return an InputStream for the data.
125: * Note that a new stream is returned each time
126: * this method is called.
127: *
128: * @return                the InputStream
129: * @exception        IOException        if no data has been set
130: */
131: @Override
132: public InputStream getInputStream() throws IOException {
133:         if (data == null)
134:          throw new IOException("no data");
135:         if (len < 0)
136:          len = data.length;
137:         return new SharedByteArrayInputStream(data, 0, len);
138: }
139:
140: /**
141: * Return an OutputStream for the data.
142: * Writing the data is not supported; an <code>IOException</code>
143: * is always thrown.
144: *
145: * @exception        IOException        always
146: */
147: @Override
148: public OutputStream getOutputStream() throws IOException {
149:         throw new IOException("cannot do this");
150: }
151:
152: /**
153: * Get the MIME content type of the data.
154: *
155: * @return        the MIME type
156: */
157: @Override
158: public String getContentType() {
159: return type;
160: }
161:
162: /**
163: * Get the name of the data.
164: * By default, an empty string ("") is returned.
165: *
166: * @return        the name of this data
167: */
168: @Override
169: public String getName() {
170: return name;
171: }
172:
173: /**
174: * Set the name of the data.
175: *
176: * @param        name        the name of this data
177: */
178: public void setName(String name) {
179:         this.name = name;
180: }
181: }